/* Form 表单类型声明 */
import type { FormRules, FormItemRule } from 'element-plus'
import { CSSProperties } from 'vue'

// 表单元素
type IFormElement =
  | 'el-cascader'
  | 'el-checkbox-group'
  | 'el-checkbox-button'
  | 'el-color-picker'
  | 'el-date-picker'
  | 'el-input'
  | 'el-input-number'
  | 'el-radio-group'
  | 'el-radio-button'
  | 'el-rate'
  | 'el-select'
  | 'el-option'
  | 'el-slider'
  | 'el-switch'
  | 'el-time-picker'
  | 'el-time-select'
  | 'el-transfer'
  | 'el-upload'
  | 'el-button'
  | 'def-icon-picker'
  | 'def-region-picker'
  | 'def-editor'
  | 'def-upload'
type IFormSubElement = 'el-option' | 'el-radio' | 'el-checkbox'
// 表单元素属性类型
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types
type TInputType = 'text' | 'password' | 'textarea'
type TPickerType =
  | 'year'
  | 'month'
  | 'date'
  | 'dates'
  | 'datetime'
  | 'week'
  | 'datetimerange'
  | 'daterange'
  | 'monthrange'
// 表单元素属性
export interface IFormElementAttrs {
  type?: TInputType | TPickerType // 类型
  placeholder?: string // 输入框占位文本
  clearable?: boolean // 是否可清空 false
  disabled?: boolean // 是否禁用 false
  showPassword?: boolean // 是否显示切换密码图标 false
}

// 表单项
export interface ILayout {
  gutter?: number // row独有
  offset?: number // col独有
  span?: number
  xs?: number
  sm?: number
  md?: number
  lg?: number
  xl?: number
}
export type TElButtonType = 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'text'
export type TElButtonSize = 'large' | 'default' | 'small'
export type TActionEvent = 'submit' | 'search' | 'reset' | 'clear'
export type TActionPosition = 'flex-start' | 'flex-end' | 'center'
export interface IChildrenData {
  label: string
  value: string
  children?: IChildrenData[]
}
export interface IFormAction {
  label: string // 按钮名称
  type?: TElButtonType // 类型
  size?: TElButtonSize // 尺寸
  icon?: string // 图标组件
  iconSize?: number // 图标大小
  event: TActionEvent // 事件名
  disabled?: boolean // 按钮是否为禁用状态
  hidden?: boolean // 按钮显隐
  actionPosition?: TActionPosition
}
// https://element-plus.gitee.io/zh-CN/component/form.html#form-item-属性
export interface IElFormItem {
  prop: string // model 的键名。在定义了 validate、resetFields 的方法时，该属性是必填的
  label?: string // 标签文本
  labelWidth?: string | number // 标签宽度，例如 '50px'。 可以使用 auto。
  required?: boolean // 是否为必填项，如不设置，则会根据校验规则确认 false
  rules?: FormItemRule | FormItemRule[] // 表单验证规则
  error?: string // 表单域验证错误时的提示信息。设置该值会导致表单验证状态变为 error，并显示该错误信息。
  showMessage?: boolean // 是否显示校验错误信息 true
  inlineMessage?: boolean // 是否在行内显示校验信息 false
}
export interface IFormItem extends IElFormItem {
  element: IFormElement // 表单项元素
  value: any // 表单项值
  children?: IChildrenData[] // 表单项元素子项
  elementAttrs?: IFormElementAttrs | any // 表单元素属性
  style?: CSSProperties // 表单项 element-item 行内样式
  hidden?: boolean // 表单项显隐
  layout?: ILayout // 表单项单个 el-row el-col响应式布局
  subElement?: IFormSubElement // 表单项子项元素
  // 按钮独有属性
  hiddenSubmit?: boolean
  hiddenSearch?: boolean
  hiddenReset?: boolean
  hiddenClear?: boolean
  action?: IFormAction[]
}

// 表单
// https://element-plus.gitee.io/zh-CN/component/form.html#form-属性
type TLabelPosition = 'left' | 'right' | 'top'
type TSize = 'large' | 'default' | 'small'
export interface IElForm {
  model?: Record<string, any> // 表单数据对象
  rules?: FormRules // 表单验证规则
  inline?: boolean // 行内表单模式 false
  labelPosition?: TLabelPosition // 表单域标签的位置， 当设置为 left 或 right 时，则也需要设置label-width属性 right
  labelWidth?: string | number // 标签的长度，例如 '50px'。 作为 Form 直接子元素的 form-item 会继承该值。 可以使用 auto。
  labelSuffix?: string // 表单域标签的后缀
  hideRequiredAsterisk?: boolean // 是否显示必填字段的标签旁边的红色星号 false
  showMessage?: boolean // 是否显示校验错误信息 true
  inlineMessage?: boolean // 是否以行内形式展示校验信息 false
  statusIcon?: boolean // 是否在输入框中显示校验结果反馈图标 false
  validateOnRuleChange?: boolean // 是否在 rules 属性改变后立即触发一次验证 true
  size?: TSize // 用于控制该表单内组件的尺寸
  disabled?: boolean // 是否禁用该表单内的所有组件。 如果设置为 true, 它将覆盖内部组件的 disabled 属性。 false
}

export interface IForm extends IElForm {
  formItemList?: IFormItem[] // 表单项列表
  layout?: ILayout // 表单整体 el-row el-col 响应式布局
}
